<template>
  <div class="video-preview-component">
    <div class="video-container" :style="containerStyle">
      <video 
        ref="videoRef"
        :src="realSrc" 
        :controls="showControls" 
        :autoplay="autoplay"
        :muted="muted"
        @error="handleError"
        @loadedmetadata="handleLoadedMetadata"
      >
        <div class="video-error-slot">
          <i class="el-icon-video-camera-outline"></i>
          <p>视频加载失败</p>
        </div>
      </video>
      
      <!-- 加载中提示 -->
      <div v-if="isLoading" class="loading-overlay">
        <div class="loading-spinner">
          <i class="el-icon-loading"></i>
        </div>
      </div>
      
      <!-- 无视频源提示 -->
      <div v-if="!realSrc && !isLoading" class="no-source-slot">
        <i class="el-icon-video-camera-outline"></i>
        <p>暂无视频</p>
      </div>
    </div>
    
    <!-- 视频信息面板 -->
    <div v-if="showInfo && videoInfo" class="video-info-panel">
      <div class="info-item">
        <span class="info-label">文件名：</span>
        <span class="info-value">{{ videoInfo.name }}</span>
      </div>
      <div class="info-item">
        <span class="info-label">格式：</span>
        <span class="info-value">{{ videoInfo.format || '未知格式' }}</span>
      </div>
      <div class="info-item">
        <span class="info-label">时长：</span>
        <span class="info-value">{{ videoInfo.duration || '未知时长' }}</span>
      </div>
    </div>
  </div>
</template>

<script>
import { isExternal } from "@/utils/validate";

export default {
  name: "VideoPreview",
  props: {
    src: {
      type: String,
      default: ""
    },
    width: {
      type: [Number, String],
      default: "220px"
    },
    height: {
      type: [Number, String],
      default: "120px"
    },
    showControls: {
      type: Boolean,
      default: true
    },
    autoplay: {
      type: Boolean,
      default: false
    },
    muted: {
      type: Boolean,
      default: true
    },
    showInfo: {
      type: Boolean,
      default: true
    },
    videoName: {
      type: String,
      default: ""
    }
  },
  data() {
    return {
      isLoading: false,
      videoInfo: null
    };
  },
  computed: {
    realSrc() {
      if (!this.src) {
        return "";
      }
      let real_src = this.src.split(",")[0];
      if (isExternal(real_src)) {
        return real_src;
      }
      return process.env.VUE_APP_BASE_API + real_src;
    },
    containerStyle() {
      return {
        width: typeof this.width === "string" ? this.width : `${this.width}px`,
        height: typeof this.height === "string" ? this.height : `${this.height}px`
      };
    }
  },
  methods: {
    handleError() {
      this.isLoading = false;
      this.$emit("error");
    },
    handleLoadedMetadata() {
      this.isLoading = false;
      
      // 提取视频信息
      const video = this.$refs.videoRef;
      if (video) {
        const duration = this.formatDuration(video.duration);
        const format = this.getVideoFormat(video.src);
        
        this.videoInfo = {
          name: this.videoName || this.getFileName(video.src),
          duration,
          format
        };
        
        this.$emit("loaded", this.videoInfo);
      }
    },
    getFileName(url) {
      if (!url) return "未知文件";
      return url.substring(url.lastIndexOf('/') + 1);
    },
    getVideoFormat(url) {
      if (!url) return "";
      const ext = url.slice((url.lastIndexOf('.') - 1 >>> 0) + 2);
      return ext.toUpperCase();
    },
    formatDuration(seconds) {
      if (isNaN(seconds) || seconds <= 0) return "未知时长";
      
      const minutes = Math.floor(seconds / 60);
      const secs = Math.floor(seconds % 60);
      return `${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
    },
    playVideo() {
      const video = this.$refs.videoRef;
      if (video) {
        video.play();
      }
    },
    pauseVideo() {
      const video = this.$refs.videoRef;
      if (video) {
        video.pause();
      }
    }
  },
  mounted() {
    this.isLoading = true;
  },
  beforeDestroy() {
    this.pauseVideo();
  }
}
</script>

<style lang="scss" scoped>
.video-preview-component {
  display: flex;
  flex-direction: column;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  background-color: #fff;
  
  .video-container {
    position: relative;
    width: 100%;
    height: 100%;
    background-color: #000;
    
    video {
      width: 100%;
      height: 100%;
      object-fit: contain;
      cursor: pointer;
      
      &:hover {
        /* 鼠标悬停效果 */
        transition: all 0.3s ease;
      }
    }
    
    .video-error-slot, .no-source-slot {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      width: 100%;
      height: 100%;
      color: #909399;
      
      i {
        font-size: 60px;
        margin-bottom: 15px;
      }
      
      p {
        font-size: 14px;
      }
    }
    
    .loading-overlay {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.7);
      display: flex;
      justify-content: center;
      align-items: center;
      z-index: 10;
    }
    
    .loading-spinner {
      width: 60px;
      height: 60px;
      border: 4px solid rgba(255, 255, 255, 0.1);
      border-left-color: #409EFF;
      border-radius: 50%;
      animation: spin 1s linear infinite;
      
      i {
        font-size: 30px;
        color: #409EFF;
      }
    }
  }
  
  .video-info-panel {
    padding: 12px 15px;
    background-color: #f5f7fa;
    
    .info-item {
      display: flex;
      align-items: center;
      font-size: 14px;
      margin-bottom: 8px;
      
      &:last-child {
        margin-bottom: 0;
      }
    }
    
    .info-label {
      color: #909399;
      width: 60px;
      font-weight: normal;
    }
    
    .info-value {
      color: #606266;
      flex: 1;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
}

@keyframes spin {
  to { transform: rotate(360deg); }
}
</style>